<template>
  <el-form-item
    :rules="item.rule"
    :label="item.label"
    :prop="item.prop"
    class="uploadCom"
  >
    <ul class="file-list" v-if="neuFileList.length > 0 && !item.hideFileList">
      <li class="file-li" v-for="(item, index) in neuFileList" :key="index">
        <a class="file-a" :title="item.attName || item.name">
          <i class="file-icon-type"></i>
          {{ item.attName || item.name }}
        </a>
        <label class="file-icon-label">{{ item.crterTime | crterTime }}</label>
        <i
          class="el-icon-download"
          v-if="showDownload"
          @click="download(item)"
        ></i>
        <i
          class="el-icon-remove"
          v-if="showRemove"
          @click="beforeRemove(item)"
        ></i>
      </li>
    </ul>
    <el-upload
      v-loading="loading"
      v-if="showButton"
      :disabled="item.disabled === undefined ? false : item.disabled"
      v-model="formData[item.prop]"
      :action="baseUrl + item.url || '127.0.0.1'"
      ref="upload"
      :on-preview="handlePreview"
      :on-remove="handleRemove"
      :before-remove="beforeRemove"
      :accept="item.accept"
      :on-change="onChange"
      :on-progress="onProgress"
      :on-success="onSuccess"
      :before-upload="beforeAvatarUpload"
      :on-error="onError"
      :multiple="item.multiple === undefined ? false : item.multiple"
      :show-file-list="false"
      :limit="limitNum"
      name="files"
      :on-exceed="handleExceed"
      :file-list="neuFileList"
      :auto-upload="item.autoUpload || false"
    >
      <el-button
        type="primary"
        size="medium"
        :disabled="item.disabled === undefined ? false : item.disabled"
      >
        {{
          item.props.buttonName
            ? item.props.buttonName
            : constans.component_btn_upload
        }}
      </el-button>
      <div v-show="!item.hideTip" slot="tip" class="el-upload__tip">
        {{ item.ps ? item.ps : constans.component_btn_upload_explain }}
      </div>
    </el-upload>
  </el-form-item>
</template>

<script>
import constans from "../Core/json/constans";
import Message from "../../utils/Messager";
import moment from "moment";

export default {
  name: "uploadCom",
  props: {
    item: {
      type: Object,
      default: () => {
        return {};
      }
    },
    formData: {
      type: Object,
      default: () => {
        return {};
      }
    },
    isReset: {
      type: Boolean,
      default: () => {
        return false;
      }
    }
  },
  data() {
    return {
      isCanUpload: false,
      constans,
      neuFileList: [],
      baseUrl: "",
      loading: false,
      config: {
        messagerLimit: ""
      }
    };
  },
  filters: {
    crterTime(str) {
      return str
        ? moment(str).format("YYYY-MM-DD")
        : moment().format("YYYY-MM-DD");
    }
  },
  computed: {
    limitNum() {
      return this.item.props && this.item.props.limit
        ? this.item.props.limit
        : null;
    },
    showDownload() {
      let result =
        this.item.props.showDownload === undefined
          ? true
          : this.item.props.showDownload;
      return result;
    },
    showRemove() {
      let result =
        this.item.props.showRemove === undefined
          ? true
          : this.item.props.showRemove;
      return result;
    },
    showButton() {
      let result =
        this.item.props.showButton === undefined
          ? true
          : this.item.props.showButton;
      return result;
    }
  },
  watch: {
    isReset(newVal, oldVal) {
      if (newVal) {
        // 重置数据
        this.neuFileList =
          this.formData[this.item.prop] === null
            ? []
            : this.formData[this.item.prop];
        this.formData[this.item.propOther] = null;
      }
    },
    formData: {
      handler(newVal, oldVal) {
        this.neuFileList =
          newVal[this.item.prop] === null ? [] : newVal[this.item.prop];
      },
      deep: false
    },
    neuFileList(newVal = [], oldVal) {
      if (newVal && newVal.length && newVal.length > 0 && newVal[0]) {
        this.formData[this.item.prop] = newVal.filter(res => res.attAddr);
        // 处理主动赋值的file文件
        const currentFiles =
          newVal.filter(res => !res.attAddr && res.raw).map(res => res.raw) ||
          [];
        const otherFiles = newVal.filter(res => !res.attAddr && !res.raw) || [];
        let propOther = currentFiles.concat(otherFiles);
        this.formData[this.item.propOther] = propOther;
      } else {
        this.formData[this.item.prop] = null;
        this.formData[this.item.propOther] = null;
      }
    }
  },
  methods: {
    /*上传部分*/
    handleRemove(file, fileList) {
      console.log(file, fileList);
    },
    handlePreview(file) {
      console.log(file);
    },
    handleExceed(files, fileList) {
      Message.error("当前限制最多选择 " + this.limitNum + " 个文件");
    },
    beforeRemove(curItem) {
      if (this.item.hideFileList) {
        return;
      }
      Utils.$confirm({
        type: "warning",
        title: "确定移除?",
        confirm: () => {
          this.remove(curItem);
        }
      });
    },
    handleFile(file, fileList) {
      this.isCanUpload = false;
      this.config.messagerLimit = Utils.Consts.MESSAGER_LIMIT.ONE;
      let fileLimit = this.item.fileLimit ? this.item.fileLimit : {};
      let typeFlag = true;
      let sizeFlag = true;
      let maxSizeFlag = true;
      let sameFlag = true;
      let _deleteUids = [];
      let _sameUids = [];
      let sumSize = 0;
      // 处理文件列表
      fileList.forEach((_file, _index) => {
        if (fileLimit) {
          if (!_file.name) {
            _file.name = _file.attName;
          }
          let _name = _file.name.split(".");
          let fileType = _name[_name.length - 1];
          let fileSize = _file.size
            ? _file.size
            : _file.attSize
            ? _file.attSize
            : 0;
          if (!fileSize) {
            console.error("文件大小未获取，可能需要排查。");
          }
          sumSize += fileSize;
          if (
            fileLimit.type !== undefined &&
            fileLimit.type !== "" &&
            fileLimit.type !== "*" &&
            fileLimit.type.toUpperCase().indexOf(fileType) === -1 &&
            fileLimit.type.toLowerCase().indexOf(fileType) === -1
          ) {
            typeFlag = false;
            _deleteUids.push(_file.uid);
          }
          if (fileLimit.size !== undefined && fileLimit.size !== 0) {
            const realSize =
              fileLimit.sizeType === Utils.Consts.FILE_SIZE.KB
                ? fileLimit.size * 1024
                : fileLimit.size * 1024 * 1024;
            sizeFlag = !(fileSize > realSize);
            if (!sizeFlag) {
              _deleteUids.push(_file.uid);
            }
          }
        }
        fileList.forEach((forfile, index) => {
          let forRaw = forfile.raw;
          let raw = _file.raw;
          if (
            forRaw &&
            raw &&
            forRaw.name === raw.name &&
            forRaw.lastModified === raw.lastModified &&
            forRaw.size === raw.size &&
            forRaw.type === raw.type &&
            forRaw.uid !== raw.uid
          ) {
            sameFlag = false;
            if (!_sameUids.find(suid => suid == forRaw.uid)) {
              _sameUids = [..._sameUids, forRaw.uid, raw.uid];
              _deleteUids.push(_file.uid);
            }
            return false;
          }
        });
      });

      if (fileLimit.maxSize !== undefined && fileLimit.maxSize !== 0) {
        const maxSize =
          fileLimit.sizeType === Utils.Consts.FILE_SIZE.KB
            ? fileLimit.maxSize * 1024
            : fileLimit.maxSize * 1024 * 1024;
        maxSizeFlag = sumSize <= maxSize;
      }
      if (!typeFlag) {
        Message.error(fileLimit.typeError);
      } else if (!sizeFlag) {
        Message.error(fileLimit.sizeError);
      } else if (!sameFlag) {
        Message.error("请勿重复添加!");
      } else if (!maxSizeFlag) {
        Message.error(fileLimit.maxSizeError);
      }

      if (!typeFlag || !sizeFlag || !sameFlag) {
        // 只删除单个超出范围的文件
        const isRemove = uid => _deleteUids.find(_uid => uid === _uid);
        this.neuFileList = fileList.filter(obj => !isRemove(obj.uid));
        const currentFiles =
          this.$refs.upload.uploadFiles
            .filter(obj => !isRemove(obj.uid) && obj.raw)
            .map(res => res.raw) || [];
        const otherFiles =
          this.$refs.upload.uploadFiles.filter(
            obj => !isRemove(obj.uid) && !obj.raw
          ) || [];
        this.formData[this.item.propOther] = currentFiles.concat(otherFiles);
      } else if (!maxSizeFlag) {
        // 文件总大小超出范围，删除本次提交的所有文件
        const neuFileList = _.cloneDeep(this.neuFileList);
        const currentFiles =
          neuFileList
            .filter(res => !res.attAddr && res.raw)
            .map(res => res.raw) || [];
        const otherFiles =
          neuFileList.filter(res => !res.attAddr && !res.raw) || [];
        let propOther = currentFiles.concat(otherFiles);
        this.neuFileList = neuFileList;
        this.formData[this.item.propOther] = propOther;
      } else {
        this.isCanUpload = true;
        this.neuFileList = fileList;
        this.formData[this.item.propOther] = this.$refs.upload.uploadFiles.map(
          res => res.raw
        );
      }
      this.config.messagerLimit = Utils.Consts.MESSAGER_LIMIT.DEFAULT;
    },
    onChange(file, fileList) {
      this.handleFile(file, fileList);
      return;
    },
    onProgress(event, file, fileList) {
      this.loading = true;
    },
    onSuccess(response, file, fileList) {
      this.loading = false;
      if (response.code === 0) {
        this.item.onSuccess({
          ...file,
          attUploadId: response.data.attUploadId
        });
      }
    },
    beforeAvatarUpload(file) {
      return this.isCanUpload;
    },
    onError(err, file, fileList) {
      this.loading = false;
    },
    async download(curItem) {
      if (this.item.download) {
        this.item.download(curItem);
        return;
      }
      if (curItem.attAddr) {
        try {
          this.item.beforeDownload && this.item.beforeDownload();
          // 下载服务器上传的文件
          let downloadUrl = this.item.downLoadUrl || "/common/download";
          let params = {
            attUpldId: curItem.attUpldId,
            attAddr: curItem.attAddr,
            attName: curItem.attName
          };
          if (curItem.includeDate) {
            params.includeDate = curItem.includeDate;
          }
          Utils.Loader.download(downloadUrl, params);
        } finally {
          this.item.afterDownload && this.item.afterDownload();
        }
      }
    },
    remove(curItem) {
      let deepFileList = _.cloneDeep(this.neuFileList);
      _.remove(deepFileList, function(file) {
        return (
          (curItem.uid && curItem.uid === file.uid) ||
          (curItem.attAddr && curItem.attAddr === file.attAddr)
        );
      });
      this.neuFileList = deepFileList;
      if (this.item.remove) {
        this.item.remove(curItem);
      }
    }
  },
  mounted() {
    if (process.env.baseURL) {
      this.baseUrl = process.env.baseURL;
    }

    if (this.formData[this.item.prop]) {
      this.neuFileList = this.formData[this.item.prop];
    } else {
      this.neuFileList = this.formData[this.item.prop] = [];
    }
  }
};
</script>

<style scoped lang="scss">
.uploadCom {
  ::v-deep {
    .el-form-item__content {
      flex-flow: column;
    }
  }
}

.file-list {
  [class^="file-icon-"],
  [class*=" file-icon-"] {
    font-family: "element-icons" !important;
    speak: none;
    font-style: normal;
    font-weight: normal;
    font-variant: normal;
    text-transform: none;
    line-height: 1;
    vertical-align: baseline;
    display: inline-block;
    -webkit-font-smoothing: antialiased;
  }

  margin: 4px 0 20px 0;
  padding: 0;
  list-style: none;

  li {
    &:hover {
      background-color: #f5f7fa;
      color: #1b65b9;
    }

    -webkit-transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
    transition: all 0.5s cubic-bezier(0.55, 0, 0.1, 1);
    font-size: 14px;
    color: #606266;
    line-height: 1.8;
    margin-top: 5px;
    position: relative;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
    border-radius: 4px;
    width: 100%;

    .file-icon-label {
      position: absolute;
      right: 60px;
      width: 90px;
      top: 2px;
      display: block;
      line-height: inherit;
    }
  }
}

.file-a {
  &:hover {
    color: #1b65b9;
    cursor: pointer;
  }

  color: #606266;
  display: block;
  margin-right: 170px;
  overflow: hidden;
  padding-left: 4px;
  text-overflow: ellipsis;
  -webkit-transition: color 0.3s;
  transition: color 0.3s;
  white-space: nowrap;

  .file-icon-type {
    height: 100%;
    margin-right: 7px;
    color: #909399;
    line-height: inherit;
  }

  .file-icon-type:before {
    content: "\E785";
    box-sizing: border-box;
    font-family: inherit;
  }
}

.el-icon-remove,
.el-icon-download {
  /*display: none;*/
  position: absolute;
  top: 5px;
  right: 5px;
  cursor: pointer;
  opacity: 0.75;
  /*color: #606266;*/
}

.el-icon-remove {
  right: 26px;
}

.file-li:hover {
  .el-icon-remove,
  .el-icon-download {
    display: inline-block;
  }
}

.iconicon-download:hover,
.el-icon-remove:hover {
  opacity: 1;
}

.el-upload__tip {
  font-size: 12px;
  font-family: "Microsoft YaHei", "微软雅黑", Arial, sans-serif,
    "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB";
  font-weight: 400;
  color: rgba(144, 147, 153, 1);
  line-height: 14px;
}
</style>
